home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / TTY.C < prev    next >
C/C++ Source or Header  |  1991-02-16  |  7KB  |  340 lines

  1. /*
  2.  * Mg 2b  (turboc 1.5/MSC 1.5)
  3.  *   IBM-PC and compatible BIOS based display driver.
  4.  *   - this will tend to be a bit slower than a driver that
  5.  *     writes directly to the memory mapped screen, but with
  6.  *     the large # of display adapters floating around, I'd
  7.  *     rather let the bios do the work.
  8.  * 
  9.  *     I DO recommend FANSI-CONSOLE which significantly speeds
  10.  *     up display bios calls, however.
  11.  */
  12. #include    "def.h"
  13. #include    <dos.h>
  14.  
  15. #define    BEL    0x07            /* BEL character.        */
  16.  
  17. extern    int    ttrow;
  18. extern    int    ttcol;
  19. extern    int    tttop;
  20. extern    int    ttbot;
  21. extern    int    tthue;
  22.  
  23. static int biocol = 0;
  24.  
  25. int    tceeol = 2;            /* Costs are set later */
  26. int    tcinsl = 5;
  27. int    tcdell = 5;
  28.  
  29. static    int insdel = TRUE;    /* Do we have both insert & delete line? */
  30. static int rendition =0x07;
  31.  
  32. int    ttputc();
  33.  
  34. /*
  35.  * Initialize the terminal when the editor
  36.  * gets started up.
  37.  */
  38. ttinit() {
  39. }
  40.  
  41. /*
  42.  * Clean up the terminal, in anticipation of
  43.  * a return to the command interpreter.
  44.  */
  45. tttidy() {
  46. }
  47.  
  48. /*
  49.  * Move the cursor to the specified
  50.  * origin 0 row and column position.
  51.  */
  52. ttmove(row, col) {
  53.     ttcol = col;
  54.     ttrow = row;
  55.     _move(row, col);
  56. }
  57.  
  58. _move(row, col) {
  59.     union REGS rg;
  60.  
  61.     biocol = col;
  62.     rg.h.ah = 2;        /* set cursor position function code */
  63.     rg.h.dl = col;
  64.     rg.h.dh = row;
  65.     rg.h.bh = 0;        /* set screen page number */
  66.     int86(0x10, &rg, &rg);
  67. }
  68.  
  69. /*
  70.  * Erase to end of line.
  71.  */
  72. tteeol() {
  73.     union REGS rg;
  74.  
  75.     rg.h.ah = 9;    /* write character/rendition */
  76.     rg.h.bh = 0;
  77.     rg.x.cx = ncol-biocol;
  78.     rg.h.al = ' ';
  79.     rg.h.bl = rendition;
  80.  
  81.     int86(0x10, &rg, &rg);
  82. }
  83.  
  84. /*
  85.  * Erase to end of page.
  86.  */
  87. tteeop() {
  88.     ttdell(ttrow, nrow, nrow - ttrow);
  89. }
  90.  
  91. /*
  92.  * Make a noise.
  93.  */
  94. ttbeep() {
  95.     union REGS rg;
  96.  
  97.     rg.h.ah = 14;    /* write tty */
  98.     rg.h.al = BEL;
  99.  
  100.     int86(0x10, &rg, &rg);
  101. }
  102.  
  103. /*
  104.  * Insert nchunk blank line(s) onto the
  105.  * screen, scrolling the last line on the
  106.  * screen off the bottom.
  107.  */
  108. ttinsl(row, bot, nchunk) {
  109.     union REGS rg;
  110.     
  111.     if (row == bot) {        /* Case of one line insert is     */
  112.     ttmove(row, 0);        /*    special            */
  113.     tteeol();
  114.     return;
  115.     }
  116.  
  117.     rg.h.ah = 7;    /* scroll down */
  118.     rg.h.bh = 0x07;
  119.     rg.h.al = nchunk;
  120.     rg.h.ch = row;
  121.     rg.h.cl = 0;
  122.     rg.h.dh = bot;
  123.     rg.h.dl = ncol - 1;
  124.  
  125.     int86(0x10, &rg, &rg);
  126. }
  127.  
  128. /*
  129.  * Delete nchunk line(s) from "row", replacing the
  130.  * bottom line on the screen with a blank line. 
  131.  */
  132.  
  133. ttdell(row, bot, nchunk)
  134. {
  135.     union REGS rg;
  136.  
  137.     if (row == bot) {        /* One line special case    */
  138.     ttmove(row, 0);
  139.     tteeol();
  140.     return;
  141.     }
  142.     rg.h.ah = 6;    /* scroll up */
  143.     rg.h.bh = 0x07;
  144.     rg.h.al = nchunk;
  145.     rg.h.ch = row;
  146.     rg.h.cl = 0;
  147.     rg.h.dh = bot;
  148.     rg.h.dl = ncol - 1;
  149.  
  150.     int86(0x10, &rg, &rg);
  151. }
  152.  
  153. /*
  154.  * Switch to full screen scroll. This is
  155.  * used by "spawn.c" just before is suspends the
  156.  * editor, and by "display.c" when it is getting ready
  157.  * to exit.
  158.  */
  159. ttnowindow()
  160. {
  161. }
  162.  
  163. /*
  164.  * Set the current writing color to the
  165.  * specified color. Watch for color changes that are
  166.  * not going to do anything (the color is already right)
  167.  * and don't send anything to the display.
  168.  * The rainbow version does this in putline.s on a
  169.  * line by line basis, so don't bother sending
  170.  * out the color shift.
  171.  */
  172. ttcolor(color) register int color; {
  173.     if (color != tthue) {
  174.     if (color == CTEXT) {        /* Normal video.    */
  175.         rendition = 0x07;
  176.     } else if (color == CMODE) {    /* Reverse video.    */
  177.         rendition = 0x70;
  178.     }
  179.     tthue = color;            /* Save the color.    */
  180.     }
  181. }
  182.  
  183. /*
  184.  * This routine is called by the
  185.  * "refresh the screen" command to try and resize
  186.  * the display. The new size, which must be deadstopped
  187.  * to not exceed the NROW and NCOL limits, it stored
  188.  * back into "nrow" and "ncol". Display can always deal
  189.  * with a screen NROW by NCOL. Look in "window.c" to
  190.  * see how the caller deals with a change.
  191.  */
  192. ttresize() {
  193.     setttysize();
  194. }
  195.  
  196. /* calculate the cost of doing string s */
  197. charcost (s) char *s; {
  198.     return strlen(s);
  199. }
  200.  
  201. ttputc(c)
  202. unsigned char c;
  203. {
  204.     union REGS rg;
  205.  
  206.     if (c == '\b') {
  207.     if (biocol-1 > 0) {
  208.         _move(ttrow, biocol-1);
  209.     }
  210.     return;
  211.     }
  212.     else if (c == '\r') {
  213.     _move(ttrow, 0);
  214.     return;
  215.     }
  216.     rg.h.ah = 9;    /* write character/rendition */
  217.     rg.h.bh = 0;
  218.     rg.x.cx = 1;
  219.     rg.h.al = c;
  220.     rg.h.bl = rendition;
  221.  
  222.     int86(0x10, &rg, &rg);
  223.  
  224.     if (biocol+1 >= ncol)
  225.     _move(ttrow + 1, 0);
  226.     else
  227.     _move(ttrow, biocol + 1);
  228. }
  229.  
  230. struct nap
  231.     {
  232.     long napvalue;
  233.     long basetime;
  234.     };
  235.  
  236. ttwait()
  237.     {
  238.     struct nap timer;
  239.     napstart(200, &timer);
  240.     while (napchk(&timer) == 0)
  241.     if (typeahead())
  242.         return 0;
  243.     return 1;
  244.     }
  245.  
  246. /***************************/
  247. /* MSDOS time functions    */
  248. /***************************/
  249.  
  250. /* Apparantly Turbo C has a sleep library routine; MSC doesn't -jbs */
  251.  
  252. #define gettime(_a) ((((long)(_a.x.cx)) << 16)+_a.x.dx)
  253.  
  254. #ifdef MSC
  255. sleep(amount)
  256.     {
  257.     while (amount--)
  258.     nap(100);
  259.     }
  260. #endif
  261.  
  262. /* nap in units of 100ths of seconds via busy loops. */
  263. nap(amount)
  264.     {
  265.     struct nap tim;
  266.     napstart(amount, &tim);
  267.     while(napchk(&tim) == 0)
  268.     ;
  269.     }
  270.  
  271. napstart(amount,sav)
  272. int amount;
  273. register struct nap *sav;
  274.     {
  275.     union REGS inregs, outregs;
  276.     int hunds, secs;
  277.  
  278.     inregs.h.ah = 0x2c;            /* get time */
  279.     int86(0x21, &inregs, &outregs);
  280.  
  281.     /* glitch in hardware RTC (time warp) makes this necessary */
  282.     inregs = outregs;
  283.     inregs.h.dl = 0;        /* seconds counter may be slow to increment */
  284.     if (inregs.h.dh > 0)
  285.     --inregs.h.dh;        /* paranoia */
  286.     if (inregs.h.cl > 0)
  287.     --inregs.h.cl;        /* more paranoia */
  288.     /* end of glitch handling */
  289.  
  290.     sav->basetime = gettime(inregs);    /* in case of wraparound */
  291.  
  292.     /* convert hundredths of seconds to future time structure */
  293.     secs = outregs.h.dh;
  294.     hunds = outregs.h.dl + amount;
  295.  
  296.     while (hunds >= 100) {
  297.     hunds -= 100;
  298.     ++secs;
  299.     }
  300.     outregs.h.dl = hunds;
  301.     while (secs >= 60) {
  302.     secs -= 60;
  303.     ++outregs.h.cl;            /* increment minutes */
  304.     }
  305.     outregs.h.dh = secs;
  306.  
  307.     /* check for minute and hour wraparound */
  308.     if (outregs.h.cl >= 60)
  309.     {
  310.     outregs.h.cl -= 60;
  311.     ++outregs.h.ch;            /* increment hours */
  312.     }
  313.     if (outregs.h.ch >= 24)
  314.     {
  315.     outregs.h.ch -= 24;
  316.     }
  317.     sav->napvalue = gettime(outregs);
  318.     }
  319.  
  320. napchk(sav)
  321. register struct nap *sav;
  322.     {
  323.     union REGS inregs, outregs;
  324.     long current;
  325.  
  326.     inregs.h.ah = 0x2c;            /* get time */
  327.     int86(0x21, &inregs, &outregs);
  328.  
  329.     current = gettime(outregs);
  330.  
  331.     if(sav->napvalue > sav->basetime)
  332.     {
  333.     if (current >= sav->napvalue || current < sav->basetime)
  334.         return 1;
  335.     }
  336.     else if (current >= sav->napvalue && current < sav->basetime)
  337.     return 1;
  338.     return 0;
  339.     }
  340.